<!DOCTYPE html>
<html lang="zh-CN">
  <head>
    <meta charset="UTF-8" />
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1.0, user-scalable=no"
    />
    <title>俄罗斯方块 - 移动版</title>
    <script src="https://cdn.tailwindcss.com"></script>
    <link
      href="https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/css/font-awesome.min.css"
      rel="stylesheet"
    />
    <script>
      tailwind.config = {
        theme: {
          extend: {
            colors: {
              primary: "#3B82F6",
              secondary: "#10B981",
              dark: "#1E293B",
              light: "#F8FAFC",
              tetris: {
                i: "#06B6D4",
                j: "#2563EB",
                l: "#F59E0B",
                o: "#FBBF24",
                s: "#10B981",
                t: "#8B5CF6",
                z: "#EF4444",
              },
            },
            fontFamily: {
              game: ['"Press Start 2P"', "cursive", "sans-serif"],
            },
          },
        },
      };
    </script>
    <style type="text/tailwindcss">
      @layer utilities {
        .text-shadow {
          text-shadow: 2px 2px 0px rgba(0, 0, 0, 0.3);
        }
        .grid-bg {
          background-image: linear-gradient(#333 1px, transparent 1px),
            linear-gradient(90deg, #333 1px, transparent 1px);
        }
        .pixel-corners {
          clip-path: polygon(
            0% 4px,
            4px 4px,
            4px 0%,
            calc(100% - 4px) 0%,
            calc(100% - 4px) 4px,
            100% 4px,
            100% calc(100% - 4px),
            calc(100% - 4px) calc(100% - 4px),
            calc(100% - 4px) 100%,
            4px 100%,
            4px calc(100% - 4px),
            0% calc(100% - 4px)
          );
        }
        .touch-button {
          touch-action: manipulation;
          -webkit-tap-highlight-color: transparent;
          user-select: none;
          -webkit-user-select: none;
        }
        .game-area {
          max-width: 100vw;
          height: calc(100vh - 180px); /* 减去标题和控制栏的高度 */
          overflow: hidden;
          display: flex;
          flex-direction: row;
          align-items: center;
          justify-content: center;
          gap: 8px;
        }

        .game-board {
          display: flex;
          flex-direction: column;
          align-items: center;
        }

        .game-info {
          display: flex;
          flex-direction: column;
          gap: 8px;
          min-width: 120px;
        }

        /* 小屏幕响应式设计 */
        @media (max-width: 480px) {
          .game-area {
            flex-direction: column;
            gap: 4px;
          }

          .game-info {
            flex-direction: row;
            min-width: auto;
            width: 100%;
            justify-content: space-around;
          }

          .game-info > div {
            flex: 1;
            max-width: 150px;
          }
        }
        .mobile-controls {
          position: fixed;
          bottom: 0;
          left: 0;
          right: 0;
          background: rgba(30, 41, 59, 0.95);
          backdrop-filter: blur(10px);
          border-top: 2px solid #334155;
          z-index: 10;
        }
        .swipe-area {
          position: absolute;
          top: 0;
          left: 0;
          right: 0;
          bottom: 0;
          z-index: 1;
        }

        .preview-container {
          background: linear-gradient(
            135deg,
            rgba(30, 41, 59, 0.9),
            rgba(51, 65, 85, 0.8)
          );
          border: 1px solid rgba(148, 163, 184, 0.3);
          box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.3),
            0 2px 4px -1px rgba(0, 0, 0, 0.2),
            inset 0 1px 0 rgba(255, 255, 255, 0.1);
        }

        .preview-canvas {
          background: linear-gradient(135deg, #1e293b, #334155);
          border: 2px solid rgba(148, 163, 184, 0.4);
          box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.3),
            0 1px 2px rgba(0, 0, 0, 0.2);
        }
      }
    </style>
    <link
      href="https://fonts.googleapis.com/css2?family=Press+Start+2P&display=swap"
      rel="stylesheet"
    />
  </head>
  <body
    class="bg-gradient-to-br from-dark to-gray-800 min-h-screen text-light overflow-hidden"
  >
    <!-- 游戏标题 -->
    <div class="text-center py-2 px-4">
      <h1
        class="text-[clamp(1.2rem,4vw,2rem)] font-game text-primary text-shadow"
      >
        俄罗斯方块
      </h1>
    </div>

    <!-- 游戏区域 -->
    <div class="game-area px-2">
      <!-- 游戏画布区域 -->
      <div class="game-board">
        <div class="relative">
          <canvas
            id="tetrisCanvas"
            class="border-2 border-gray-700 bg-gray-900 pixel-corners shadow-lg"
          ></canvas>

          <!-- 触摸滑动区域 -->
          <div id="swipeArea" class="swipe-area"></div>

          <!-- 游戏暂停覆盖层 -->
          <div
            id="pauseOverlay"
            class="absolute inset-0 bg-dark/80 flex items-center justify-center hidden"
          >
            <div class="text-center p-4">
              <p class="font-game text-lg mb-2 text-yellow-400">游戏暂停</p>
              <p class="text-sm text-gray-300">点击继续</p>
            </div>
          </div>

          <!-- 游戏结束覆盖层 -->
          <div
            id="gameOverOverlay"
            class="absolute inset-0 bg-dark/80 flex items-center justify-center hidden"
          >
            <div
              class="text-center p-4 bg-gray-800 border-2 border-red-500 rounded-lg"
            >
              <p class="font-game text-lg mb-2 text-red-400">游戏结束</p>
              <p class="text-lg mb-2">得分: <span id="finalScore">0</span></p>
              <button
                id="restartBtn"
                class="mt-2 bg-primary hover:bg-primary/80 text-white py-2 px-4 rounded font-bold touch-button"
              >
                重新开始
              </button>
            </div>
          </div>
        </div>
      </div>

      <!-- 游戏信息面板 -->
      <div class="game-info">
        <!-- 分数面板 -->
        <div class="preview-container rounded-xl p-4 backdrop-blur-sm">
          <h2
            class="text-center text-xs font-bold mb-3 text-gray-200 uppercase tracking-wide"
          >
            分数
          </h2>
          <div class="flex justify-center items-center">
            <p
              id="score"
              class="text-2xl text-center font-game text-yellow-400 drop-shadow-lg"
            >
              0
            </p>
          </div>
        </div>

        <!-- 下一个方块预览 -->
        <div class="preview-container rounded-xl p-4 backdrop-blur-sm">
          <h2
            class="text-center text-xs font-bold mb-3 text-gray-200 uppercase tracking-wide"
          >
            下一个
          </h2>
          <div class="flex justify-center items-center">
            <canvas
              id="nextPieceCanvas"
              class="preview-canvas rounded-lg"
              style="width: 80px; height: 80px"
            ></canvas>
          </div>
        </div>
      </div>
    </div>

    <!-- 移动端控制按钮 -->
    <div class="mobile-controls p-2">
      <!-- 游戏控制按钮 -->
      <div class="flex gap-2 mb-2">
        <button
          id="startBtn"
          class="flex-1 bg-green-600 hover:bg-green-500 text-white py-2 px-3 rounded font-bold touch-button text-sm"
        >
          开始
        </button>
        <button
          id="pauseBtn"
          class="flex-1 bg-yellow-600 hover:bg-yellow-500 text-white py-2 px-3 rounded font-bold touch-button text-sm"
        >
          暂停
        </button>
      </div>

      <!-- 方向控制 -->
      <div class="grid grid-cols-3 gap-1 mb-2">
        <div></div>
        <button
          id="rotateBtn"
          class="bg-gray-700 hover:bg-gray-600 p-2 rounded touch-button"
        >
          <i class="fa fa-rotate-right text-base"></i>
        </button>
        <div></div>
        <button
          id="leftBtn"
          class="bg-gray-700 hover:bg-gray-600 p-2 rounded touch-button"
        >
          <i class="fa fa-arrow-left text-base"></i>
        </button>
        <button
          id="downBtn"
          class="bg-gray-700 hover:bg-gray-600 p-2 rounded touch-button"
        >
          <i class="fa fa-arrow-down text-base"></i>
        </button>
        <button
          id="rightBtn"
          class="bg-gray-700 hover:bg-gray-600 p-2 rounded touch-button"
        >
          <i class="fa fa-arrow-right text-base"></i>
        </button>
      </div>

      <!-- 快速操作 -->
      <div class="flex gap-2">
        <button
          id="hardDropBtn"
          class="flex-1 bg-purple-600 hover:bg-purple-500 text-white py-2 px-3 rounded font-bold touch-button text-sm"
        >
          直接落地
        </button>
      </div>

      <!-- 操作说明 -->
      <div class="mt-2 text-xs text-gray-400 text-center">
        <p>滑动屏幕移动方块 | 点击旋转 | 长按加速</p>
      </div>
    </div>

    <script>
      // 游戏配置
      const COLS = 10;
      const ROWS = 20;
      let BLOCK_SIZE = 20; // 移动端使用更小的方块
      const NEXT_PIECE_SIZE = 4;

      // 方块形状和颜色定义
      const SHAPES = {
        I: [
          [0, 0, 0, 0],
          [1, 1, 1, 1],
          [0, 0, 0, 0],
          [0, 0, 0, 0],
        ],
        J: [
          [1, 0, 0],
          [1, 1, 1],
          [0, 0, 0],
        ],
        L: [
          [0, 0, 1],
          [1, 1, 1],
          [0, 0, 0],
        ],
        O: [
          [1, 1],
          [1, 1],
        ],
        S: [
          [0, 1, 1],
          [1, 1, 0],
          [0, 0, 0],
        ],
        T: [
          [0, 1, 0],
          [1, 1, 1],
          [0, 0, 0],
        ],
        Z: [
          [1, 1, 0],
          [0, 1, 1],
          [0, 0, 0],
        ],
      };

      const COLORS = {
        I: "#06B6D4",
        J: "#2563EB",
        L: "#F59E0B",
        O: "#FBBF24",
        S: "#10B981",
        T: "#8B5CF6",
        Z: "#EF4444",
        empty: "#1E293B",
        border: "#334155",
      };

      // 获取DOM元素
      const canvas = document.getElementById("tetrisCanvas");
      const ctx = canvas.getContext("2d");
      const nextPieceCanvas = document.getElementById("nextPieceCanvas");
      const nextCtx = nextPieceCanvas.getContext("2d");
      const scoreElement = document.getElementById("score");
      const finalScoreElement = document.getElementById("finalScore");
      const startBtn = document.getElementById("startBtn");
      const pauseBtn = document.getElementById("pauseBtn");
      const restartBtn = document.getElementById("restartBtn");
      const leftBtn = document.getElementById("leftBtn");
      const rightBtn = document.getElementById("rightBtn");
      const downBtn = document.getElementById("downBtn");
      const rotateBtn = document.getElementById("rotateBtn");
      const hardDropBtn = document.getElementById("hardDropBtn");
      const pauseOverlay = document.getElementById("pauseOverlay");
      const gameOverOverlay = document.getElementById("gameOverOverlay");
      const swipeArea = document.getElementById("swipeArea");

      // 触摸控制变量
      let touchStartX = 0;
      let touchStartY = 0;
      let touchStartTime = 0;
      let isLongPress = false;
      let longPressTimer = null;
      let lastMoveTime = 0;
      const MOVE_THROTTLE = 100; // 移动节流时间(毫秒)
      const SWIPE_THRESHOLD = 30; // 滑动阈值
      const LONG_PRESS_TIME = 500; // 长按时间

      // 动态设置画布尺寸
      function setupCanvas() {
        // 计算可用空间 - 考虑水平布局
        const availableHeight = window.innerHeight - 180; // 减去标题和控制栏高度
        const availableWidth = Math.min(window.innerWidth - 200, 300); // 减去信息面板宽度

        // 根据可用空间计算合适的方块大小
        const maxBlockSizeByWidth = Math.floor(availableWidth / COLS);
        const maxBlockSizeByHeight = Math.floor(availableHeight / ROWS);

        // 选择较小的值以确保画布完全可见
        BLOCK_SIZE = Math.min(maxBlockSizeByWidth, maxBlockSizeByHeight, 25); // 最大25px

        // 确保最小方块大小
        BLOCK_SIZE = Math.max(BLOCK_SIZE, 15);

        canvas.width = COLS * BLOCK_SIZE;
        canvas.height = ROWS * BLOCK_SIZE;
        canvas.style.width = canvas.width + "px";
        canvas.style.height = canvas.height + "px";

        // 设置下一个方块预览画布尺寸
        const previewBlockSize = 20; // 固定预览方块大小，确保清晰度
        nextPieceCanvas.width = NEXT_PIECE_SIZE * previewBlockSize;
        nextPieceCanvas.height = NEXT_PIECE_SIZE * previewBlockSize;

        console.log(
          `画布尺寸: ${canvas.width}x${canvas.height}, 方块大小: ${BLOCK_SIZE}px`
        );
      }

      // 游戏状态
      let board = createEmptyBoard();
      let currentPiece = null;
      let nextPiece = null;
      let score = 0;
      let dropInterval = 1000;
      let dropTimer = null;
      let isGameOver = false;
      let isPaused = false;

      // 创建空的游戏板
      function createEmptyBoard() {
        return Array(ROWS)
          .fill()
          .map(() => Array(COLS).fill(0));
      }

      // 随机生成新方块
      function createNewPiece() {
        const keys = Object.keys(SHAPES);
        const tetromino = keys[Math.floor(Math.random() * keys.length)];

        return {
          shape: SHAPES[tetromino],
          color: COLORS[tetromino],
          type: tetromino,
          x: Math.floor((COLS - SHAPES[tetromino][0].length) / 2),
          y: 0,
        };
      }

      // 检查碰撞
      function checkCollision(piece, offsetX = 0, offsetY = 0) {
        // 检查piece是否存在
        if (!piece || !piece.shape) {
          return true; // 如果piece不存在，视为碰撞
        }

        for (let y = 0; y < piece.shape.length; y++) {
          for (let x = 0; x < piece.shape[y].length; x++) {
            if (piece.shape[y][x]) {
              const newX = piece.x + x + offsetX;
              const newY = piece.y + y + offsetY;

              if (newX < 0 || newX >= COLS || newY >= ROWS) {
                return true;
              }

              if (newY >= 0 && board[newY][newX]) {
                return true;
              }
            }
          }
        }
        return false;
      }

      // 旋转方块
      function rotatePiece(piece) {
        if (!piece || !piece.shape || isPaused || isGameOver) return;

        const rotated = piece.shape[0].map((_, index) =>
          piece.shape.map((row) => row[index]).reverse()
        );

        const originalShape = piece.shape;
        piece.shape = rotated;

        if (checkCollision(piece)) {
          if (!checkCollision(piece, 1, 0)) {
            piece.x += 1;
          } else if (!checkCollision(piece, -1, 0)) {
            piece.x -= 1;
          } else if (!checkCollision(piece, 0, 1)) {
            piece.y += 1;
          } else {
            piece.shape = originalShape;
          }
        }
      }

      // 锁定当前方块到游戏板上
      function lockPiece() {
        for (let y = 0; y < currentPiece.shape.length; y++) {
          for (let x = 0; x < currentPiece.shape[y].length; x++) {
            if (currentPiece.shape[y][x]) {
              const newX = currentPiece.x + x;
              const newY = currentPiece.y + y;

              if (newY < 0) {
                gameOver();
                return;
              }

              board[newY][newX] = currentPiece.color;
            }
          }
        }

        clearLines();

        currentPiece = nextPiece;
        nextPiece = createNewPiece();

        if (checkCollision(currentPiece)) {
          gameOver();
        }

        draw();
      }

      // 消除已满的行
      function clearLines() {
        let linesCleared = 0;

        for (let y = ROWS - 1; y >= 0; y--) {
          if (board[y].every((cell) => cell !== 0)) {
            board.splice(y, 1);
            board.unshift(Array(COLS).fill(0));
            linesCleared++;
            y++;
          }
        }

        if (linesCleared > 0) {
          const lineScores = [0, 100, 300, 500, 800];
          score += lineScores[linesCleared];
          scoreElement.textContent = score;

          dropInterval = Math.max(100, 1000 - (score / 1000) * 500);
          restartDropTimer();
        }
      }

      // 绘制游戏
      function draw() {
        ctx.fillStyle = COLORS.empty;
        ctx.fillRect(0, 0, canvas.width, canvas.height);

        drawGrid();

        for (let y = 0; y < ROWS; y++) {
          for (let x = 0; x < COLS; x++) {
            if (board[y][x]) {
              drawBlock(ctx, x, y, board[y][x]);
            }
          }
        }

        if (currentPiece) {
          for (let y = 0; y < currentPiece.shape.length; y++) {
            for (let x = 0; x < currentPiece.shape[y].length; x++) {
              if (currentPiece.shape[y][x]) {
                const drawX = currentPiece.x + x;
                const drawY = currentPiece.y + y;
                if (drawY >= 0) {
                  drawBlock(ctx, drawX, drawY, currentPiece.color);
                }
              }
            }
          }
        }

        drawNextPiece();
      }

      // 绘制网格线
      function drawGrid() {
        ctx.strokeStyle = COLORS.border;
        ctx.lineWidth = 0.5;

        for (let x = 0; x <= COLS; x++) {
          ctx.beginPath();
          ctx.moveTo(x * BLOCK_SIZE, 0);
          ctx.lineTo(x * BLOCK_SIZE, canvas.height);
          ctx.stroke();
        }

        for (let y = 0; y <= ROWS; y++) {
          ctx.beginPath();
          ctx.moveTo(0, y * BLOCK_SIZE);
          ctx.lineTo(canvas.width, y * BLOCK_SIZE);
          ctx.stroke();
        }
      }

      // 绘制单个方块
      function drawBlock(context, x, y, color) {
        const xPos = x * BLOCK_SIZE;
        const yPos = y * BLOCK_SIZE;

        context.fillStyle = color;
        context.fillRect(xPos, yPos, BLOCK_SIZE - 1, BLOCK_SIZE - 1);

        context.fillStyle = rgbaFromHex(color, 0.3);
        context.fillRect(xPos, yPos, BLOCK_SIZE - 1, (BLOCK_SIZE - 1) / 2);

        context.fillStyle = rgbaFromHex(color, 0.7);
        context.fillRect(
          xPos,
          yPos + (BLOCK_SIZE - 1) / 2,
          BLOCK_SIZE - 1,
          (BLOCK_SIZE - 1) / 2
        );
      }

      // 绘制下一个方块预览
      function drawNextPiece() {
        const previewBlockSize = 20; // 固定预览方块大小

        nextCtx.fillStyle = COLORS.empty;
        nextCtx.fillRect(0, 0, nextPieceCanvas.width, nextPieceCanvas.height);

        nextCtx.strokeStyle = COLORS.border;
        nextCtx.lineWidth = 0.5;

        for (let x = 0; x <= NEXT_PIECE_SIZE; x++) {
          nextCtx.beginPath();
          nextCtx.moveTo(x * previewBlockSize, 0);
          nextCtx.lineTo(x * previewBlockSize, nextPieceCanvas.height);
          nextCtx.stroke();
        }

        for (let y = 0; y <= NEXT_PIECE_SIZE; y++) {
          nextCtx.beginPath();
          nextCtx.moveTo(0, y * previewBlockSize);
          nextCtx.lineTo(nextPieceCanvas.width, y * previewBlockSize);
          nextCtx.stroke();
        }

        if (nextPiece) {
          const offsetX = Math.floor(
            (NEXT_PIECE_SIZE - nextPiece.shape[0].length) / 2
          );
          const offsetY = Math.floor(
            (NEXT_PIECE_SIZE - nextPiece.shape.length) / 2
          );

          for (let y = 0; y < nextPiece.shape.length; y++) {
            for (let x = 0; x < nextPiece.shape[y].length; x++) {
              if (nextPiece.shape[y][x]) {
                drawPreviewBlock(
                  nextCtx,
                  x + offsetX,
                  y + offsetY,
                  nextPiece.color,
                  previewBlockSize
                );
              }
            }
          }
        }
      }

      // 绘制预览方块
      function drawPreviewBlock(context, x, y, color, blockSize) {
        const xPos = x * blockSize;
        const yPos = y * blockSize;

        context.fillStyle = color;
        context.fillRect(xPos, yPos, blockSize - 1, blockSize - 1);

        context.fillStyle = rgbaFromHex(color, 0.3);
        context.fillRect(xPos, yPos, blockSize - 1, (blockSize - 1) / 2);

        context.fillStyle = rgbaFromHex(color, 0.7);
        context.fillRect(
          xPos,
          yPos + (blockSize - 1) / 2,
          blockSize - 1,
          (blockSize - 1) / 2
        );
      }

      // 辅助函数: 将十六进制颜色转换为带透明度的rgba
      function rgbaFromHex(hex, alpha) {
        const r = parseInt(hex.slice(1, 3), 16);
        const g = parseInt(hex.slice(3, 5), 16);
        const b = parseInt(hex.slice(5, 7), 16);
        return `rgba(${r}, ${g}, ${b}, ${alpha})`;
      }

      // 移动方块
      function movePiece(dx, dy) {
        if (isPaused || isGameOver || !currentPiece) return;

        if (!checkCollision(currentPiece, dx, dy)) {
          currentPiece.x += dx;
          currentPiece.y += dy;
          draw();
          return true;
        } else if (dy > 0) {
          lockPiece();
          return false;
        }
        return false;
      }

      // 方块直接落地
      function hardDrop() {
        if (isPaused || isGameOver || !currentPiece) return;

        let dropped = 0;
        while (movePiece(0, 1)) {
          dropped++;
        }
        score += Math.floor(dropped / 2);
        scoreElement.textContent = score;
      }

      // 开始下落计时器
      function startDropTimer() {
        if (dropTimer) clearInterval(dropTimer);

        dropTimer = setInterval(() => {
          if (!isPaused && !isGameOver) {
            movePiece(0, 1);
          }
        }, dropInterval);
      }

      // 重启下落计时器
      function restartDropTimer() {
        clearInterval(dropTimer);
        startDropTimer();
      }

      // 开始游戏
      function startGame() {
        board = createEmptyBoard();
        score = 0;
        isGameOver = false;
        isPaused = false;
        scoreElement.textContent = score;

        currentPiece = createNewPiece();
        nextPiece = createNewPiece();

        pauseOverlay.classList.add("hidden");
        gameOverOverlay.classList.add("hidden");

        startDropTimer();
        draw();
        drawNextPiece(); // 确保下一个方块预览正确显示
      }

      // 暂停/继续游戏
      function togglePause() {
        if (isGameOver) return;

        isPaused = !isPaused;

        if (isPaused) {
          clearInterval(dropTimer);
          pauseOverlay.classList.remove("hidden");
        } else {
          startDropTimer();
          pauseOverlay.classList.add("hidden");
        }
      }

      // 游戏结束
      function gameOver() {
        isGameOver = true;
        clearInterval(dropTimer);
        finalScoreElement.textContent = score;
        gameOverOverlay.classList.remove("hidden");
      }

      // 触摸事件处理
      function handleTouchStart(e) {
        e.preventDefault();
        const touch = e.touches[0];
        touchStartX = touch.clientX;
        touchStartY = touch.clientY;
        touchStartTime = Date.now();
        isLongPress = false;

        // 开始长按计时
        longPressTimer = setTimeout(() => {
          isLongPress = true;
          // 长按加速下落
          if (!isPaused && !isGameOver && currentPiece) {
            movePiece(0, 1);
          }
        }, LONG_PRESS_TIME);
      }

      function handleTouchMove(e) {
        e.preventDefault();
        const touch = e.touches[0];
        const deltaX = touch.clientX - touchStartX;
        const deltaY = touch.clientY - touchStartY;
        const currentTime = Date.now();

        // 节流移动操作
        if (currentTime - lastMoveTime < MOVE_THROTTLE) return;

        if (
          Math.abs(deltaX) > SWIPE_THRESHOLD ||
          Math.abs(deltaY) > SWIPE_THRESHOLD
        ) {
          clearTimeout(longPressTimer);

          if (Math.abs(deltaX) > Math.abs(deltaY)) {
            // 水平滑动
            if (deltaX > SWIPE_THRESHOLD) {
              movePiece(1, 0);
            } else if (deltaX < -SWIPE_THRESHOLD) {
              movePiece(-1, 0);
            }
          } else {
            // 垂直滑动
            if (deltaY > SWIPE_THRESHOLD) {
              movePiece(0, 1);
            }
          }

          lastMoveTime = currentTime;
          touchStartX = touch.clientX;
          touchStartY = touch.clientY;
        }
      }

      function handleTouchEnd(e) {
        e.preventDefault();
        clearTimeout(longPressTimer);

        const touchDuration = Date.now() - touchStartTime;
        const touch = e.changedTouches[0];
        const deltaX = touch.clientX - touchStartX;
        const deltaY = touch.clientY - touchStartY;

        // 短按且移动距离小，视为点击旋转
        if (
          touchDuration < LONG_PRESS_TIME &&
          Math.abs(deltaX) < 10 &&
          Math.abs(deltaY) < 10
        ) {
          if (!isPaused && !isGameOver && currentPiece) {
            rotatePiece(currentPiece);
            draw();
          }
        }
      }

      // 事件监听 - 触摸控制
      swipeArea.addEventListener("touchstart", handleTouchStart, {
        passive: false,
      });
      swipeArea.addEventListener("touchmove", handleTouchMove, {
        passive: false,
      });
      swipeArea.addEventListener("touchend", handleTouchEnd, {
        passive: false,
      });

      // 事件监听 - 按钮控制
      startBtn.addEventListener("click", startGame);
      pauseBtn.addEventListener("click", togglePause);
      restartBtn.addEventListener("click", startGame);
      leftBtn.addEventListener("click", () => movePiece(-1, 0));
      rightBtn.addEventListener("click", () => movePiece(1, 0));
      downBtn.addEventListener("click", () => movePiece(0, 1));
      rotateBtn.addEventListener("click", () => {
        rotatePiece(currentPiece);
        draw();
      });
      hardDropBtn.addEventListener("click", hardDrop);

      // 暂停覆盖层点击继续
      pauseOverlay.addEventListener("click", togglePause);

      // 窗口大小改变时重新设置画布
      window.addEventListener("resize", setupCanvas);

      // 初始化游戏
      window.addEventListener("load", () => {
        setupCanvas();
        board = createEmptyBoard();
        nextPiece = createNewPiece();
        drawNextPiece();
      });

      // 防止页面滚动
      document.addEventListener(
        "touchmove",
        function (e) {
          e.preventDefault();
        },
        { passive: false }
      );

      // 防止双击缩放
      document.addEventListener("touchend", function (e) {
        e.preventDefault();
      });
    </script>
  </body>
</html>
